#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/*
Structure to handle requests and responses
char name[10] - request name
void *data - pointer to data array
*/
typedef struct
    {
    char name[10];
    int *data;
    } message;

// itoa implemetation
char* itoa(int val, int base)
    {
    static char buf[32]={0};
    int i=30;
    if ( val == 0 )
        {
        return "0";
        }
    for(; val && i ; --i, val /= base)
        {
        buf[i]="0123456789abcdef"[val%base];
        }
    return &buf[i+1];
    }

/*  Data serialization: message->string
 *  @param1 [msg] = message datastructure to be serialized into a string
 *  @param2 [str] = string to store serialized message
 * */
void serialize(message* msg, char* str)
    {
    char buffer[50] = "";
    // Add request
    strcat(buffer,msg->name);
    // Add full separator
    strcat(buffer,":");
    // If there's data start serialization loop for data
    if ( msg->data != NULL )
        {
        // find data array length
        int size = sizeof(msg->data)/sizeof(int);
        int i;
        // process each ellement
        for(i=0; i<=size; i++)
            {
            strcat(buffer,itoa(msg->data[i],10));
            strcat(buffer,":");
            }
        }
    // If there's no data add null
    else
        {
        strcat(buffer,"NULL:");
        }
    strcpy(str,buffer);
    }

/*  Data deserialization: string->message
 *  @param1 [msg] = message datastructure to be serialized into a string
 *  @param2 [str] = string to store serialized message
 * */
void deserialize(char* str,message* msg)
    {
    char temp[64];
    int i = 0;
    int j = 0;
    int k = 0;
    // Parsing command string
    while ( str[i] != ':' && i < strlen(str) )
        {
        temp[i] = str[i];
        i++;
        temp[i] = '\0';
        }
    i++;
    strcpy(msg->name,temp);
    // Parsing data if any
    while ( i < strlen(str) )
        {
        if ( str[i] != ':' )
            {
            temp[k] = str[i];
            k++;
            }
        else
            {
            // if data is not NULL save else assign null
            if ( strncmp("NULL",temp,4) )
                {
                msg->data[j] = atoi(temp);
                }
            else
                {
                msg->data = NULL;
                break;
                }
            j++;
            k = 0;
            }
        i++;
        }

    }

/* Main function for serialization testing */
/*int main()
    {
    message msg;
    char buf[255];
    int i;
    int tmp[3] = {3,2,1};
    int tmp2[3];

    strcpy(msg.name,"FORCE UPD");
    msg.data = NULL;

    serialize(&msg,buf);

    printf("%s \n",buf);

    strcpy(msg.name,"");
    msg.data = tmp2;

    deserialize(buf,&msg);

    printf("Request: %s \n",msg.name);
    printf("Data: ");
    if ( msg.data != NULL )
        {
        for ( i = 0 ; i < sizeof(msg.data)/sizeof(int) + 1; i++ )
            {
            printf("%d ",msg.data[i]);
            }
        }
    else
        {
        printf("NULL");
        }
    printf("\n");

    return 0;
    }*/
